package org.itboys.weixin.tools;

import org.itboys.commons.utils.json.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;


public class WXUtils {
	/**
	 * 用于暂存accessToken的map key为微信appId 会有定时线程定时清除的
	 */
	private static final Map<String, String> accessTokenMap = new HashMap<String, String>();
	private static Timer timer = null;
	private static final String JSTICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=";
	
	public static final String APPID = "wx8afd7d88805fc3ba";
	public static final String APPSECRET = "eaa8dfbb0a67e84815f9f9e56bbc4fc6";
	public static  Logger logger = LoggerFactory.getLogger(WXUtils.class);
	/**
	 * 获取jsapi_ticket
	 * 
	 * @return
	 */
	public static String getJsTicket(String appId, String appsecret) {
		logger.info("appId:"+appId+"appsecret"+appsecret);
//		String accessToken = accessTokenMap.get(appId);
//		logger.info("accessToken:"+accessToken);
//		if (accessToken != null) {
//			return accessToken;
//		}
		String accessToken = WeixinUtils.getAccessToken(appId, appsecret);
		logger.info("accessToken:"+accessToken);
		String url = JSTICKET_URL + accessToken;
		String jsonToken = HttpHelper.doGet(url);
		logger.info("jsonToken:"+jsonToken);
		JsToken token = JsonUtils.jsonToObject(JsToken.class, jsonToken);
		logger.info("token:"+token);
		accessTokenMap.put(appId, token.getTicket());
		if (timer == null) {
			timer = new Timer();
		}
		long delay = token.getExpires_in();
		if (delay > 50) {// 其实有7200秒的有效时间 不知道有效时间会不会变
							// 反正提前50秒去清空本地map的accessToken
			delay = delay - 50;
		}
		timer.schedule(new ClearAccessTokenTask(appId), delay*1000);
		return token.getTicket();
	}

	/**
	 * 生成签名
	 * 
	 * @param timestamp
	 * @param nonce
	 * @return
	 */
	public static String checkSignature(String timestamp, String nonce,
			String url, String appId, String appsecret) {
		String content = "jsapi_ticket=" + getJsTicket(appId, appsecret) + "&noncestr=" + nonce
				+ "&timestamp=" + timestamp + "&url=" + url;
		// MessageDigest md = null;
		String tmpStr = null;
		try {
			/*
			 * md = MessageDigest.getInstance("SHA-1"); //
			 * 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest =
			 * md.digest(content.toString().getBytes()); tmpStr =
			 * byteToStr(digest);
			 */
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(content.getBytes("UTF-8"));
			tmpStr = byteToStr(crypt.digest());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return tmpStr;
	}

	/**
	 * 将字节数组转换为十六进制字符串
	 * 
	 * @param byteArray
	 * @return
	 */
	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 * 
	 * @param mByte
	 * @return
	 */
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];

		String s = new String(tempArr);
		return s;
	}

	static class ClearAccessTokenTask extends TimerTask {
		private String appId;

		public ClearAccessTokenTask(String appId) {
			this.appId = appId;
		}

		@Override
		public void run() {
			synchronized (accessTokenMap) {
				accessTokenMap.remove(appId);
			}
		}
	}

	public static String getDownUrl(String mediaId) {
		return "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token="
				+ WeixinUtils.getAccessToken(APPID, APPSECRET) + "&media_id="
				+ mediaId;
	}
	public static String getDownUrl(String mediaId,String appId,String appsecret) {
		return "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token="
				+ WeixinUtils.getAccessToken(appId, appsecret) + "&media_id="
				+ mediaId;
	}

	/**
	 * 通过HTTP方式获取文件
	 * 
	 * @param strUrl
	 *            http地址
	 * @param fileName
	 *            存储到本地的路径
	 * @return
	 * @throws IOException
	 */
	public static boolean getRemoteFile(String strUrl, String fileName)
			throws IOException {
		URL url = new URL(strUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		DataInputStream input = new DataInputStream(conn.getInputStream());
		DataOutputStream output = new DataOutputStream(new FileOutputStream(
				fileName));
		byte[] buffer = new byte[1024 * 8];
		int count = 0;
		while ((count = input.read(buffer)) > 0) {
			output.write(buffer, 0, count);
		}
		output.close();
		input.close();
		return true;
	}


	
}
